package com.qingzhi.spring.demo.controller;

import com.qingzhi.spring.demo.model.UserInfo;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/request")
@RestController
public class RequestController {

    // 单个参数进行传递
    @RequestMapping("/r1")
    public String r1(String keyword) {
        //如果不进行传参数的话，这里的引用类型会是null
        return "接收参数 keyword: " + keyword;
    }

    @RequestMapping("/r2")
    public String r2(Integer number) {
        //如果不进行传参数的话，这里的引用类型会是null
        return "接收参数 number: " + number;
    }

    @RequestMapping("/r3")
    public String r3(int number) {
        // 如果不进行传参数的话，这里就会出错
        return "接收参数 number: " + number;
    }

    // 传递多个参数
    @RequestMapping("/r4")
    public String r4(String userName,String password) {
        return "接收参数 userName: " + userName + "，password" + password;
    }

    // 传递对象
    @RequestMapping("/r5")
    public String r5(UserInfo userInfo) {
        return "接收参数 userInfo: " + userInfo.toString();
    }

    //有时候我们前端传送的和我们想要的名字可能是不一样的，我们就要使用 @RequestParam 这个注释来绑定参数
    @RequestMapping("/r6")
    public String r6(@RequestParam(value = "q",required = false) String keyword) {
        // 这里的 q 传过来的数据就会绑定到 keyword 中
        // 这个时候 q 就会变成一个必传参数了，如果想要不传之=值，就要进行参数的增加 required = false
        return "接收参数 keyword: " + keyword;
    }

    // 传递数组
    @RequestMapping("/r7")
    public String r7(String[] arr) {
        return "接收参数 arr: " + Arrays.toString(arr);
    }

    //传递集合
    @RequestMapping("/r8")
    public String r8(@RequestParam List<Integer> list) {
        // 对于集合来说，我们同样需要使用 @RequestParam 来绑定
        return "接收参数 list: " + list;
    }

    // 传递Json
    // 使用 @RequestBody 这个标签。请求正文的意思，Spring会根究这个标签进行把前端传递过来的 json 转换成对应绑定的对象，这里是UserInfo
    @RequestMapping("/r9")
    public String r9(@RequestBody UserInfo userInfo) {
        return userInfo.toString();
    }

    // 获得 URL 中的参数
    // @PathVariable 这个就是 路径变量，{}中的数据就是一个变量，要和对应的传参的参数名一致
    @RequestMapping("/r10/{articleID}")
    public String r10(@PathVariable Integer articleID) {
        return "文章ID" + articleID;
    }

    //同样可以传多个参数，有多少个参数就有多少个 @PathVariable 这个标签
    @RequestMapping("/r11/{type}/{articleID}")
    public String r111(@PathVariable Integer articleID,@PathVariable("type") String articleType) {
        return "文章ID：" + articleID + " 文章类型：" + articleType;
    }

    // 上传文件
    @RequestMapping("/r12")
    public String r12(@RequestPart("file12") MultipartFile file) throws IOException {
        System.out.println(file.getOriginalFilename());
        //上传文件
        file.transferTo(new File("D:\\图片\\" + file.getOriginalFilename()));

        return "上传文件成功";
    }


    @RequestMapping("/r13")
    public String r13(Boolean number) {
        return "接收参数 number: " + number;
    }

    // 用户希望从 http 请求中获得什么，都可以从 HttpServletRequest 中获得(请求)
    // 用户希望给客户端返回什么，都可以通过 HttpServletResponse 来返回(响应)

    // 获得 Cookie，这个事存储在客户端的
    // 传统的方式
    // 最长使用的
    @RequestMapping("/getCookie")
    public String r14(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        //进行coolies的字符串拼接
        StringBuilder stringBuilder = new StringBuilder();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                stringBuilder.append(cookie.getName() + ":" + cookie.getValue() + " ");
            }
        }
        return "Cookie的信息：" + stringBuilder;
    }

    // 使用标签的方式
    @RequestMapping("/getCookie2")
    public String r15(@CookieValue("name") String name) {
        return "Cookie的name信息：" + name;
    }

    // 对于 Session 的操作，对于Session呢是在服务端的，我们需要先存储再进行获取
    // 对于 Session的存储
    // 不同的客户端就会得到不同的 sessionID
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request) {
        // 就是从 cookie 中获得sessionID ，根据 sessionID获得Session对象
        // 如果sessionID不存在的话，默认获得一个新的 session，如果参数为false的话，如果不存在就会是null
        HttpSession session = request.getSession();
        // Session默认存储在内存中
        // 登录用户的存储
        session.setAttribute("userName","zhangsan");
        session.setAttribute("age",15);
        return "Session设置成功";
    }

    // 对 Session 的获取
    // 最常使用的
    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest request) {
        // 就是从 cookie 中获得sessionID ，根据 sessionID获得Session对象
        // 这个是当其没有 sessionID 的时候就会返回null，有就返回对应的 Session对象
        HttpSession session = request.getSession(false);
        if (session == null) {
            return "用户为登录";
        }else {
            String userName = (String) session.getAttribute("userName");
            int age = (int) session.getAttribute("age");
            return "用户的登录名称为：" + userName + " 年龄为：" + age;
        }
    }

    // 对 Session 的获取的简便方法
    @RequestMapping("/getSession2")
    // 这个HttpSession session相当于 HttpSession session = request.getSession();
    public String getSession2(HttpSession session) {
        // 就是从 cookie 中获得sessionID ，根据 sessionID获得Session对象
        String userName = (String) session.getAttribute("userName");
        int age = (int) session.getAttribute("age");
        return "用户的登录名称为：" + userName + " 年龄为：" + age;
    }

    // 对 Session 的获取的最简便方法
    @RequestMapping("/getSession36")
    public String getSession3(@SessionAttribute("userName") String userName) {
        // 就是从 cookie 中获得sessionID ，根据 sessionID获得Session对象
        return "用户的登录名称为：" + userName;
    }

    // 获取 Header
    // 传统的写法
    // 这种写法经常使用
    @RequestMapping("/getHeader")
    public String getHeader(HttpServletRequest request) {
        // 根究传入的参数来获取 Header 中对应的数据
        String userAgent = request.getHeader("User-Agent");
        return "从header中获得的User-Agent：" + userAgent;
    }

    // 简写的写法
    @RequestMapping("/getHeader2")
    public String getHeader2(@RequestHeader("User-Agent") String userAgent) {
        return "从header中获得的User-Agent：" + userAgent;
    }
}
